package com.sc.nft.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.sc.nft.dao.*;
import com.sc.nft.entity.*;
import com.sc.nft.enums.CarveUpPoolLogStatusEmum;
import com.sc.nft.enums.PrizeDrawActivityPoolBonusTaypEnum;
import com.sc.nft.enums.task.ActivityTypeEnum;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.service.MallOrderProductService;
import com.sc.nft.service.MallOrderService;
import com.sc.nft.service.PrizeDrawActivityAwardLogService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import com.sc.nft.service.CarveUpPoolService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 * 瓜分活动总奖池服务接口实现
 *
 * @author Sun
 * @since 2023-09-14 11:25:32
 * @description 由 Mybatisplus Code Generator 创建
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class CarveUpPoolServiceImpl implements CarveUpPoolService {

    private final CarveUpPoolDao carveUpPoolDao;
    private final PrizeDrawActivityPoolDao prizeDrawActivityPoolDao;
    private final ActivityBasicsDao activityBasicsDao;
    private final FilterIncomeListDao filterIncomeListDao;
    private final PrizeDrawActivityPoolSettleLogDao prizeDrawActivityPoolSettleLogDao;
    private final MallOrderService mallOrderService;

    private final MallOrderProductService mallOrderProductService;


    @Override
    public String getResidualPrizePool() {
        CarveUpPool residualPrizePool = carveUpPoolDao.getResidualPrizePool();
        return residualPrizePool.getAmount().setScale(2, BigDecimal.ROUND_DOWN).toPlainString();
    }

    @Override
    public boolean subAmountByActivityBasicsId(Long activityId, BigDecimal initPoolReserve) {
        CarveUpPool oldCarveUpPool = carveUpPoolDao.getById(1L);

        Boolean falg = carveUpPoolDao.subAmountByActivityBasicsId(initPoolReserve,oldCarveUpPool.getId());
        CarveUpPoolLog carveUpPoolLog = new CarveUpPoolLog();
        carveUpPoolLog.setActivityId(activityId);
        carveUpPoolLog.setAmount(initPoolReserve);
        carveUpPoolLog.setFromAmount(oldCarveUpPool.getAmount());
        carveUpPoolLog.setToAmount(oldCarveUpPool.getAmount().subtract(initPoolReserve));
        carveUpPoolLog.setStatus(CarveUpPoolLogStatusEmum.FREEZE);
        carveUpPoolLog.setIsAdd(Boolean.FALSE);
        carveUpPoolLog.insert();


        return falg;
    }

    @Override
    public boolean addAmountByActivityBasicsId(Long activityId, BigDecimal initPoolReserve) {
        CarveUpPool oldCarveUpPool = carveUpPoolDao.getById(1L);

        Boolean falg = carveUpPoolDao.addAmountByActivityBasicsId(initPoolReserve,oldCarveUpPool.getId());
        CarveUpPoolLog carveUpPoolLog = new CarveUpPoolLog();
        carveUpPoolLog.setActivityId(activityId);
        carveUpPoolLog.setAmount(initPoolReserve);
        carveUpPoolLog.setFromAmount(oldCarveUpPool.getAmount());
        carveUpPoolLog.setToAmount(oldCarveUpPool.getAmount().add(initPoolReserve));
        carveUpPoolLog.setStatus(CarveUpPoolLogStatusEmum.DELETE);
        carveUpPoolLog.setIsAdd(Boolean.FALSE);
        carveUpPoolLog.insert();
        return falg;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addPrizeDrawActivityPoolAmountLog(Long userId,BigDecimal payAmount,Long productId,Long orderId, PrizeDrawActivityPoolBonusTaypEnum bonusType) {
        Boolean isSuccess = false;
        //校验奖池是否存在
        List<PrizeDrawActivityPool> list = prizeDrawActivityPoolDao.getOneByLinkIdAndBonusType(null,bonusType);
        for (PrizeDrawActivityPool prizeDrawActivityPool : list) {
            if(ObjectUtil.isNull(prizeDrawActivityPool)){
                continue;
            }

            ActivityBasics activityBasics = activityBasicsDao.getById(prizeDrawActivityPool.getActivityId());
            if(ObjectUtil.isNull(activityBasics)){
                continue;
            }

            //校验当前活动是否上架
            if(activityBasics.getStatus().intValue() ==0){
                continue;
            }

            //校验当前活动是否在有效期内
            if(DateTime.now().before(activityBasics.getStartTime())){
                continue;
            }

            if(DateTime.now().isAfter(activityBasics.getEndTime())){
                continue;
            }

            PrizeDrawActivityPoolSettleLog prizeDrawActivityPoolSettleLog = new PrizeDrawActivityPoolSettleLog();
            prizeDrawActivityPoolSettleLog.setActivityId(prizeDrawActivityPool.getActivityId());
            prizeDrawActivityPoolSettleLog.setPoolId(prizeDrawActivityPool.getId());
            prizeDrawActivityPoolSettleLog.setAmount(payAmount);
            prizeDrawActivityPoolSettleLog.setBonusType(bonusType);
            prizeDrawActivityPoolSettleLog.setOrderId(orderId);
            prizeDrawActivityPoolSettleLog.setProductId(productId);
            prizeDrawActivityPoolSettleLog.setPayAmount(payAmount.setScale(3,BigDecimal.ROUND_DOWN));
            prizeDrawActivityPoolSettleLog.setLinkId(0L);
            prizeDrawActivityPoolSettleLog.setLinkName(prizeDrawActivityPool.getLinkName());
            prizeDrawActivityPoolSettleLog.setLinkScale(prizeDrawActivityPool.getLinkScale());
            prizeDrawActivityPoolSettleLog.setIsSettle(Boolean.FALSE);
            prizeDrawActivityPoolSettleLog.insert();
            isSuccess = true;
        }
        if (!isSuccess){
            // 转入公共
            addPoolAmount(payAmount);
        }
    }

    @Override
    public List<PrizeDrawActivityPoolSettleLog> getPoolSettleLogList() {
        return prizeDrawActivityPoolSettleLogDao.getPoolSettleLogList();
    }

    @Override
    public void addPoolAmount(PrizeDrawActivityPoolSettleLog prizeDrawActivityPoolSettleLog) {
        prizeDrawActivityPoolDao.addPoolAmountById(prizeDrawActivityPoolSettleLog.getPoolId(),prizeDrawActivityPoolSettleLog.getAmount());
    }

    @Override
    public void addPoolAmountAndSubFreezeAmount(Long activityId, BigDecimal poolAmount, BigDecimal subFreezeAmount) {
        CarveUpPool oldCarveUpPool = carveUpPoolDao.getById(1L);

        Boolean falg = carveUpPoolDao.addAmountByActivityBasicsId(poolAmount,oldCarveUpPool.getId());
        CarveUpPoolLog carveUpPoolLog = new CarveUpPoolLog();
        carveUpPoolLog.setActivityId(activityId);
        carveUpPoolLog.setAmount(poolAmount);
        carveUpPoolLog.setFromAmount(oldCarveUpPool.getAmount());
        carveUpPoolLog.setToAmount(oldCarveUpPool.getAmount().add(poolAmount));
        carveUpPoolLog.setStatus(CarveUpPoolLogStatusEmum.ADD);
        carveUpPoolLog.setIsAdd(Boolean.FALSE);
        carveUpPoolLog.insert();
        log.info(StrUtil.format("奖池累计奖金结果:{}",falg));
        carveUpPoolDao.subFreezeAmount(subFreezeAmount,oldCarveUpPool.getId());


    }

    @Override
    public void addPoolAmount(BigDecimal OrderDistribution) {
        CarveUpPool oldCarveUpPool = carveUpPoolDao.getById(1L);

        Boolean falg = carveUpPoolDao.addAmountByActivityBasicsId(OrderDistribution,oldCarveUpPool.getId());
        CarveUpPoolLog carveUpPoolLog = new CarveUpPoolLog();
        carveUpPoolLog.setActivityId(0L);
        carveUpPoolLog.setAmount(OrderDistribution);
        carveUpPoolLog.setFromAmount(oldCarveUpPool.getAmount());
        carveUpPoolLog.setToAmount(oldCarveUpPool.getAmount().add(OrderDistribution));
        carveUpPoolLog.setStatus(CarveUpPoolLogStatusEmum.SHARE_BENEFIT);
        carveUpPoolLog.setIsAdd(Boolean.TRUE);
        carveUpPoolLog.insert();
        log.info(StrUtil.format("奖池累计奖金结果:{}",falg));
    }

    @Override
    public void addMallOrderPrizeDrawActivityPoolAmountLog(Long mallOrderId,BigDecimal grossProfit) {
        MallOrder mallOrder = mallOrderService.getById(mallOrderId);
        if(ObjectUtil.isNull(mallOrder)){
            return;
        }

        if(mallOrder.getActivityType() != ActivityTypeEnum.SALES){
            return;
        }

        //汇入总奖池
        addPrizeDrawActivityPoolAmountLog(mallOrder.getUserId(),grossProfit,mallOrder.getId(),mallOrder.getId(),PrizeDrawActivityPoolBonusTaypEnum.IP_MALL);
    }
}